using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using FireStarterModeller.BO;
using FireStarterModeller.Logic;
using FireStarterModeller.Test.BO;
using Habanero.BO;
using Habanero.BO.ClassDefinition;
using NUnit.Framework;

namespace FireStarterModeller.Test.Logic
{
    [TestFixture]
    public class TestXmlPersistor: TestBase
    {
        private XmlPersistor CreateXmlPersistor()
        {
            return CreateXmlPersistor(new StringBuilder());
        }

        private XmlPersistor CreateXmlPersistor(StringBuilder stringBuilder)
        {
            return new XmlPersistor(new StringWriter(stringBuilder));
        }

        [Test]
        public void Test_AddBusinessObject()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = SharedTestUtils.CreateSavedDMSolution();
            XmlPersistor xmlPersistor = CreateXmlPersistor();
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            xmlPersistor.AddBusinessObject(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual(1, xmlPersistor.BusinessObjects.Count);
            Assert.Contains(dmSolution, xmlPersistor.BusinessObjects);
        }

        [Test]
        public void Test_AddBusinessObject_Twice()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = SharedTestUtils.CreateSavedDMSolution();
            XmlPersistor xmlPersistor = CreateXmlPersistor();
            xmlPersistor.AddBusinessObject(dmSolution);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            xmlPersistor.AddBusinessObject(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual(1, xmlPersistor.BusinessObjects.Count);
            Assert.Contains(dmSolution, xmlPersistor.BusinessObjects);
        }
        
        [Test]
        public void Test_Persist_Nothing()
        {
            //---------------Set up test pack-------------------
            StringBuilder stringBuilder = new StringBuilder();
            XmlPersistor xmlPersistor = CreateXmlPersistor(stringBuilder);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            xmlPersistor.Persist();
            //---------------Test Result -----------------------
            string xml = stringBuilder.ToString();
            Assert.AreEqual("<BusinessObjects />", xml);
        }

        [Test]
        public void Test_Persist_SingleBO()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = SharedTestUtils.CreateSavedDMSolution();
            StringBuilder stringBuilder = new StringBuilder();
            XmlPersistor xmlPersistor = CreateXmlPersistor(stringBuilder);
            xmlPersistor.AddBusinessObject(dmSolution);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            xmlPersistor.Persist();
            //---------------Test Result -----------------------
            string xml = stringBuilder.ToString();
            AssertHasRootTag(xml);
            StringAssert.Contains("<DMSolution", xml);
            StringAssert.Contains(string.Format(@"SolutionName=""{0}""", dmSolution.SolutionName), xml);
            ///StringAssert.Contains(, xml);
        }

        [Test]
        public void Test_Persist_TwoBOs()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = SharedTestUtils.CreateSavedDMSolution();
            DMClass dmClass = SharedTestUtils.CreateSavedDMClass();
            StringBuilder stringBuilder = new StringBuilder();
            XmlPersistor xmlPersistor = CreateXmlPersistor(stringBuilder);
            xmlPersistor.AddBusinessObject(dmSolution);
            xmlPersistor.AddBusinessObject(dmClass);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            xmlPersistor.Persist();
            //---------------Test Result -----------------------
            string xml = stringBuilder.ToString();
            AssertHasRootTag(xml);
            StringAssert.Contains("<DMSolution", xml);
            StringAssert.Contains("<DMClass", xml);
        }

        [Test]
        public void Test_Persist_InnerTypedClass()
        {
            //---------------Set up test pack-------------------
            StringBuilder stringBuilder = new StringBuilder();
            XmlPersistor xmlPersistor = CreateXmlPersistor(stringBuilder);
            ClassDef classDef = MockBo.InnerMockBo.CreateClassDef();
            ClassDef.ClassDefs.Add(classDef);
            MockBo.InnerMockBo innerMockBo = new MockBo.InnerMockBo();
            xmlPersistor.AddBusinessObject(innerMockBo);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            xmlPersistor.Persist();
            //---------------Test Result -----------------------
            string xml = stringBuilder.ToString();
            AssertHasRootTag(xml);
            StringAssert.Contains("<MockBo_x002B_InnerMockBo", xml);
        }

        [Test]
        public void Test_Persist_BoWithEnumProp()
        {
            //---------------Set up test pack-------------------
            StringBuilder stringBuilder = new StringBuilder();
            XmlPersistor xmlPersistor = CreateXmlPersistor(stringBuilder);
            ClassDef classDef = MockBo.CreateClassDefWithProp<MyEnum>();
            ClassDef.ClassDefs.Add(classDef);
            MockBo mockBo = new MockBo();
            mockBo.TestProp = MyEnum.Val2;
            xmlPersistor.AddBusinessObject(mockBo);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            xmlPersistor.Persist();
            //---------------Test Result -----------------------
            string xml = stringBuilder.ToString();
            AssertHasRootTag(xml);
            StringAssert.Contains("<MockBo", xml);
            StringAssert.Contains(@"TestProp=""Val2""", xml);
        }

        private enum MyEnum
        {
            Val1,
            Val2
        }

        private static void AssertHasRootTag(string xml)
        {
            StringAssert.StartsWith("<BusinessObjects>", xml);
            StringAssert.EndsWith("</BusinessObjects>", xml);
        }
    }
}
